import { cloneDeep, isEmpty } from 'lodash-es'

import {
  getDingConfigApi,
  getUploadKeysApi,
  loginApi,
  orgMenusQueryByCurrentUserApi,
  systemModuleGetAllApi,
} from '@/api/app'
import { res } from '@/api/app/menuData'
import { queryUserInfoApi } from '@/api/sys/organization'
import { noLoginRoutes } from '@/router/index'
import { navigateTo, redirectTo } from '@/router/navigate'
import { modal } from '@/utils/antdHelper'
import config from '@/utils/config'
import { CACHE_KEY } from '@/utils/constants'
import { Local, Session } from '@/utils/storage'
import { resetUploadKeys } from '@/utils/uploadUtil/helper'

const { defaultPageKey } = config

/**
 * @typedef {Object} Details
 * @property {Array} [areaList] 院区列表
 * @property {Array} [departmentList] 科室列表
 * @property {Array} [departmentNames] 科室名称列表
 * @property {string} [entranceId] 个人中心配置的默认系统id
 * @property {string} [entranceName] 个人中心配置的默认系统名称
 * @property {Array} [entrances] 当前登陆人所有的系统列表
 * @property {string} [fullName] 登陆人名称
 * @property {string} [id] 登陆人id
 * @property {string} [mobileNumber] 登陆人手机号
 * @property {string} [moduleId] 个人中心配置的默认系统对应的预设的系统id
 * @property {string} [moduleName] 个人中心配置的默认系统对应的预设的系统名称
 * @property {string} [organizationId] 机构id
 * @property {string} [organizationName] 机构名称
 * @property {Array} [roles] 角色列表
 */
/**
 * @typedef {Object} Authorization
 * @property {Array<string>} [authorities] 权限列表
 * @property {Details} [details] 详情
 * @property {string} [mode] 来源，default-pc端 | ding-钉钉
 * @property {string} [userId] userId
 * @property {string} [userName] userName
 */
/**
 * @typedef {Object} LoginInfo
 * @property {Authorization} [authorization] 权限信息
 * @property {boolean} [superAdmin] 是否超管
 * @property {string} [token] token
 */
/**
 * @typedef {Object} state
 * @property {boolean} [isFirstEntry] 是否初次打开界面
 * @property {boolean} [needEbeiFlag] 是否展示医贝标识
 * @property {boolean} [isLogin] 是否登陆
 * @property {LoginInfo} [loginInfo] 登录信息
 * @property {Object} [userInfo] 用户信息
 * @property {[]} [systemModuleList] 所有系统
 * @property {string} [currentEntranceId] 当前进入的系统id
 * @property {Object} [dingConfig]
 * @property {[]} [menuList] 总的菜单
 * @property {{}} [menuMap] 总的菜单平铺
 *
 *
 * @property {string} [defaultMenuPath] 系统默认界面地址
 * @property {import('react').ReactNode} [topTabExtraContent] 头部菜单右侧展示内容
 */

/**
 * @type {state}
 */
const initialState = {
  isFirstEntry: true,
  needEbeiFlag: false,
  isLogin: false,
  loginInfo: {},
  userInfo: {},
  systemModuleList: [],
  currentEntranceId: undefined,
  dingConfig: {},
  menuList: [],
  menuMap: {},

  defaultMenuPath: '',
  topTabExtraContent: undefined,
}

const namespace = 'app'

export default {
  namespace,
  state: cloneDeep(initialState),
  subscriptions: {
    // setup({ dispatch, history }) {},
    // 监听路由变化
    setup({ dispatch, history }) {
      return history.listen(async ({ pathname, search }) => {
        dispatch({
          type: 'init',
          payload: { pathname },
        })
        // 无需登陆的界面
        if (noLoginRoutes.map(({ path }) => path).includes(pathname)) {
          return
        }

        // 登陆界面
        if (pathname.includes('/login')) {
          return
        }

        let token = Session.getToken()
        // token 不存在
        if (!token) {
          redirectTo('login')
          return
        }
        const { app } = window.dvaApp._store.getState()
        if (isEmpty(app.loginInfo)) {
          const params = Local.get(CACHE_KEY.LOGIN)
          if (!params) {
            redirectTo('login')
            return
          }
          await dispatch({
            type: 'silentLogin',
            payload: params,
          })
        }
        await dispatch({
          type: 'beforOpenPage',
          payload: { pathname },
        })
      })
    },
  },
  effects: {
    /** 页面首次打开，做一些初始化的操作 */
    *init(_, { call, select, update }) {
      const { isFirstEntry } = yield select(({ app }) => app)
      if (isFirstEntry) {
        const { data } = yield call(getUploadKeysApi)
        resetUploadKeys(data || {})
        const currentEntranceId = Session.get(CACHE_KEY.CURRENT_ENTRANCE_ID)
        if (currentEntranceId) {
          yield update({
            currentEntranceId,
          })
        }
        yield update({
          needEbeiFlag: data.enableEbIcon === true,
          isFirstEntry: false,
        })
      }
    },
    /** 登录 */
    *silentLogin({ payload }, { call, select, update }) {
      /**@type {{data:LoginInfo}} */
      const { data } = yield call(loginApi, { ...payload, mode: 'default' })
      yield update({ loginInfo: data })
      // 缓存账号密码
      Local.set(CACHE_KEY.LOGIN, payload)
      const { token, authorization } = data
      // 缓存token信息
      Session.setToken(token)

      const { details } = authorization
      const { currentEntranceId } = yield select(store => store[namespace])
      if (data.superAdmin) return
      // 已设置当前系统
      if (currentEntranceId) return

      const { entranceId, entrances } = details
      let _entranceId = entranceId // 设置的默认系统
      if (!entranceId) {
        _entranceId = entrances[0].entranceId // 系统列表第一个系统
      }
      Session.set(CACHE_KEY.CURRENT_ENTRANCE_ID, _entranceId)
      yield update({ currentEntranceId: _entranceId })
    },
    /** 在新页面打开前操作 */
    *beforOpenPage({ payload }, { select, toAction, update }) {
      /** @type {state} */
      const state = yield select(store => store[namespace])
      if (!state.isLogin) {
        yield toAction('getBasicData')
        yield update({
          isLogin: true,
        })
      }
      if (payload.pathname === '/') {
        /** @type {state} */
        const state = yield select(store => store[namespace])
        navigateTo(state.defaultMenuPath)
      }
    },
    /** 获取全局基础数据 */
    *getBasicData(_, { toAction }) {
      yield toAction('getUserInfo')
      yield toAction('getSystemModuleList')
      yield toAction('getDingConfig')
      yield toAction('getDataByEntranceId')
    },
    /** 查询个人信息 */
    *getUserInfo(_, { call, update, select }) {
      let { userInfo, loginInfo } = yield select(store => store[namespace])
      if (!isEmpty(userInfo)) return
      const { data } = yield call(queryUserInfoApi)
      userInfo = data || {}
      if (loginInfo.superAdmin) {
        userInfo.organizationName = '医贝'
        userInfo.fullName = '超级管理员'
      }
      window.sessionStorage.setItem('pageTitle', userInfo.organizationName)
      yield update({ userInfo })
    },
    /** 获取所有系统 */
    *getSystemModuleList(_, { update, call, select }) {
      let { systemModuleList } = yield select(store => store[namespace])
      if (!isEmpty(systemModuleList)) return
      const { data } = yield call(systemModuleGetAllApi)
      systemModuleList = (data || []).map(i => ({
        ...i,
        id: i.moduleId,
        name: i.moduleName,
      }))
      yield update({ systemModuleList })
    },
    /** 获取钉钉端配置 */
    *getDingConfig({ payload = {} }, { call, update }) {
      const { data } = yield call(getDingConfigApi, payload)
      yield update({ dingConfig: data })
    },
    /** 切换系统 */
    *changeEntrance({ payload = {} }, { update, toAction, select }) {
      const currentEntranceId = payload.entranceId
      Session.set(CACHE_KEY.CURRENT_ENTRANCE_ID, currentEntranceId)
      yield update({
        currentEntranceId,
        topMenuList: [],
        selectedTopMenuKey: '',
      })
      yield toAction('getDataByEntranceId')
      /** @type {state} */
      const state = yield select(store => store[namespace])
      navigateTo(state.defaultMenuPath)
    },
    /** 获取系统基础数据 */
    *getDataByEntranceId(_, { toAction, select }) {
      yield toAction('getMenuList')
      /** @type {state} */
      const state = yield select(store => store[namespace])
      if (state.loginInfo.superAdmin) return
      // yield toAction('getSystemDictConfig') // 实时更新各机构下的系统字典列表
    },
    /** 获取菜单 */
    *getMenuList(_, { call, update, select }) {
      let { loginInfo, currentEntranceId } = yield select(store => store[namespace])
      let menuList = []
      if (loginInfo.superAdmin) {
        menuList = res.content
      } else {
        const { data } = yield call(orgMenusQueryByCurrentUserApi, { entranceId: currentEntranceId })
        menuList = data
        if (isEmpty(menuList)) {
          modal.error({
            content: '你无任何页面访问权限，请联系管理员',
          })
          return
        }
      }
      const privateMenus = [
        'home', // 首页
        'personalCenter', // 个人中心
      ]

      const pageKeyList = cloneDeep(privateMenus)
      /** 默认页面 */
      let defaultMenuPath = defaultPageKey
      const menuMap = {}
      const loop = list => {
        list.forEach(item => {
          if (!item.featurePath) {
            item.featurePath = item.path
          }
          const pageKey = item.featurePath
          menuMap[pageKey] = item
          if (!isEmpty(item.children)) {
            loop(item.children)
          } else {
            pageKeyList.push(pageKey)
          }
          // 配置了默认页面
          if (item.defaultMenu) {
            defaultMenuPath = pageKey
          }
        })
      }

      loop(menuList)
      yield update({
        defaultMenuPath,
        menuList,
        menuMap,
        pageKeyList,
      })
    },

    // 用户注销时删除所有信息
    *logout(_, { toAction, update }) {
      yield toAction('notice/stopWatchUnReadNotices')
      Local.clear()
      Session.clear()
      yield update({
        ...initialState,
      })
      redirectTo('login')
    },
  },
  reducers: {
    updateState(state, { payload = {} }) {
      return {
        ...state,
        ...payload,
      }
    },
  },
}
